<!-- 导入可视化 -->
<template>
  <el-dialog :title="(`${importTitle}` + $t('other.importdata'))" :close-on-press-escape="false" :show-close="false" :modal="false" :visible.sync="importVisualDialogFlag" top="0" v-dialogDrag width="900px" :before-close="beforeClose" :destroy-on-close="true">
    <div style="padding:8px">
      <el-upload :show-file-list="false" action="/" :http-request="customUpload">
        <el-button slot="trigger" icon="el-icon-upload">{{$t('other.selectFile')}}</el-button>
        <el-button style="margin-left:20px" v-show="downTemplate" icon="el-icon-download" @click="$emit('handleDownTemplate')">{{$t('other.downTem')}}</el-button>
        <div slot="tip" style="padding:8px 0">{{$t('other.templateType')}}：.xls .xlsx</div>
      </el-upload>
    </div>
    <h5 v-show="!importStatus" style="padding: 10px">{{$t('other.nochoose')}}</h5>
    <div style="padding: 10px" v-show="importStatus">
      <p>{{$t('other.importprogress')}}：<span style="padding: 0 5px; color: #589df8;">{{ percentage }}%</span>（{{$t('other.surplus')}}<span style="padding: 0 5px; color: #589df8;"> {{ percentage === 0 ? 0 : 60 - (Math.round(percentage / 100 * 60)) }} </span>{{$t('other.second')}}）</p>
      <el-progress :text-inside="true" :stroke-width="26" :percentage="percentage"></el-progress>
      <div style="width: 100%; height: 300px; background-color: #ebeef5; margin-top: 20px; padding: 1rem 0.5rem;">
        <p class="text">{{$t('other.presedataing')}}...</p>
        <p class="text">{{$t('other.readprogress')}}<span style="padding: 0 5px; color: #589df8; ">{{ totalCount }}</span>{{$t('other.datanum')}}</p>
        <p class="text">{{$t('other.importing')}}...</p>
        <p class="text">{{$t('other.importComplete')}}<span style="padding: 0 5px; color: #589df8; ">{{afterNumber}}</span>，{{$t('other.surplus')}}<span style="padding: 0 5px; color: #589df8; ">{{beforeNumber}}</span>{{$t('other.importing1')}}...</p>
        <p class="text" v-show="2 === importStatus">{{$t('other.importsuccess')}}<span style="padding: 0 5px; color: #589df8; ">{{successCount}}</span>{{$t('other.datanum')}}</p>
        <p class="text" v-show="3 === importStatus"><span style="padding: 0 5px; color: #589df8; ">{{successCount}}</span>{{$tj('other.datanum','other.importsuccess')}}<span style="padding: 0 5px; color: red;">{{failedCount}}</span>{{$t('other.datanum2')}}</p>
        <p class="text" v-show="3 === importStatus">{{$t('other.importdone')}}</p>
        <p class="text" v-show="3 === importStatus" style=" color: #589df8;">{{$t('other.importagain')}}</p>
      </div>
    </div>
    <!-- 导入进度状态 -->
    <span slot="footer" class="dialog-footer" style="display: flex; flex-direction: row-reverse;">
      <el-button v-show="importStatus == 1" type="primary" disabled :loading="true">{{$t('other.importing')}}</el-button>
      <el-button v-show="importStatus == 2" type="primary" @click="handleClose">{{$t('other.break')}}</el-button>
      <el-button v-show="importStatus == 3" type="primary" @click="handleClose">{{$t('other.downerrfile')}}</el-button>
    </span>
  </el-dialog>
</template>

<script>
import * as XLSX from 'xlsx/xlsx.mjs'

export default {
  name: "ImportVisual",
  props: [
    "importVisualDialogFlag",
    "importType",
    "importUrl",
    "downTemplate",
    "importTitle",
    "sheetKey"
  ],
  data() {
    return {
      importParams:null,
      totalCount:0,
      importStatus:0,
      beforeNumber:0,
      afterNumber:0,
      failedCount:0,
      exceptionUrl:0,
      successCount:0,
    }
  },
  computed:{
    percentage(){
      const {totalCount,successCount} = this;
      if(totalCount&&successCount){
        return Math.ceil(successCount*100/totalCount)
      }
      return 0 
    }
  },
  methods: {
    reset(){
      this.totalCount = 0;
      this.importStatus = 0;
      this.beforeNumber = 0;
      this.afterNumber = 0;
      this.failedCount = 0;
      this.exceptionUrl = 0;
      this.successCount = 0;
    },
    handleClose(){
      if(this.importStatus == 2){
        this.$emit('update:importVisualDialogFlag',false)
      }else{
        this.$emit('handleDownErrorFile',this.exceptionUrl)
      }
      this.reset()
    },
    //上传前，选择文件后
    async customUpload(upload){
      this.reset()
      const range = this.importParams.readLineNum - 1;
      let map = await this.excelSheetParsing(upload.file, range);
      console.log(map);
      if(Array.isArray(map)&&map.length == 0){
        this.reset()
        return this.$message.error(this.$t('other.emptyDataMsg'))
      }
      let fd = new FormData(),size;
      fd.append('file',upload.file);
      if(map.masterSheet&&map.masterSize){
        //多表
        size = map.masterSize;
        let masterSheet = map.masterSheet;
        this.totalCount = size;
        // 调用导入页面 =  end //////////////////////////////
  
        // 拿取主sheet的关联字段
        let ele = "关联编号";
        let subSheet = "subSheet";
        masterSheet.forEach((item) => {
          // 初始化第一个sheet子表对象属性
          item[this.sheetKey] = [];
          for (let i = 0; i < map.subSheetSize; i++) {
  
            let subName = subSheet + (i + 1);
            map[subName].forEach((x) => {
  
              // 验证是否归属主对象元素
              if (item[ele] === x[ele]) {
                // 添加第一个sheet子表对象属性
                if (i === 0) {
                  item[this.sheetKey].push(x);
                }
              }
            });
          }
        });

      }else{
        //单表
        size = map.length;
        this.totalCount = map.length;
      }
      this.importStatus = 1;

      let res;
      let num = 0;
      let arrayData = new Array();
      let excelImportSize = 100;
      const key = this.uuid();

      const masterSheet = Array.isArray(map) ? map : map.masterSheet;
      for (const item of masterSheet) {
        const index = masterSheet.indexOf(item);
        num = index + 1;
        let callEnds = num === size;
        let i = num % excelImportSize;
        arrayData[i] = item;
        if ((num % excelImportSize) == 0 || callEnds) {
          fd.set('arrayData', JSON.stringify(arrayData));
          fd.set('total', size);
          let i = 0;
          arrayData.forEach((item => {
            if (item !== null) {
              i += 1;
            }
          }))
          this.beforeNumber = size - (i + this.afterNumber);
          this.afterNumber += i;
          let importApi = `/${this.importUrl}/${this.importType}/${key}`;
          if(this.importType == 10301){
            importApi = `/${this.importUrl}/${key}`
          }
          res = await this.$post(importApi, fd);
          // 清空传入的数据
          arrayData = new Array();
        }
      }

      let resData = this.importType == 10301 ? res : res.data;
      if (resData !== undefined && resData !== null) {
        if (resData.code === "ok") {
          // 调用导入页面 = start /////////////////////////////
          let failedCount = resData.value.failedCount;
          let successCount = resData.value.successCount;
          let exceptionFileUrl = resData.value.exceptionFileUrl;
          if(failedCount !== 0) {
            this.failedCount += failedCount;
            this.exceptionUrl = exceptionFileUrl;
            this.successCount += successCount;
            this.importStatus = 3;
          } else {
            this.$message.success(this.$t('app.importMes'))
            this.importStatus = 2;
            this.successCount += successCount;
          }
        } else {
          if (num === size) {
            this.$message.error(resData.desc);
          }
        }
      }else{
        this.$message.error(this.$t('other.importFail'))
        this.reset()
      }
      console.log(res)
    },
    getImportParams(){
      if(this.importType){
        const importType = this.importType;
        this.$post(`/sysExcelImportRule/selectExcelImportDefineByRuleImportDataType/${importType}`, {}).then(res => {
          this.importParams = res.data;
        }).catch(err => {
          console.log(err);
        })
      }
    },
    readFile(file) {
      //文件读取
      return new Promise((resolve) => {
        let reader = new FileReader();
        reader.readAsBinaryString(file); //以二进制的方式读取
        reader.onload = (ev) => {
          resolve(ev.target.result);
        };
      });
    },
    // 解析excel多个sheet
    async excelSheetParsing(file, range) {
      let data = await this.readFile(file);
      // 解析二进制格式数据
      let workbook = XLSX.read(data, { type: "binary", cellDates: true });
      const obj = {};
      let size = "Size";
      let opts = { range: range, defval: "" };
      let sheetSize = workbook.SheetNames.length;
      if (sheetSize > 1) {
        obj.isSubSheet = true;
        obj.subSheetSize = sheetSize - 1;
        // 遍历多个sheet工作区
        workbook.SheetNames.forEach((item, index) => {
          if (index === 0) {
            // json数据格式
            obj.masterSheet = XLSX.utils.sheet_to_json(
              workbook.Sheets[item],
              opts
            );
            obj.masterSize = obj.masterSheet.length;
          } else {
            let subName = "subSheet" + index;
            obj[subName] = XLSX.utils.sheet_to_json(workbook.Sheets[item], opts);
            obj[subName + size] = obj[subName].length;
          }
        });
        return obj;
      }else{
        let worksheet = workbook.Sheets[workbook.SheetNames[0]];
        // 读取文件内容，（第一个sheet里的内容）
        // range：设置从第几行开始读取内容 ; defval 为空时显示列值为空
        // json数据格式
        let result = XLSX.utils.sheet_to_json(worksheet, {
          range: range,
          defval: "",
        });
        // 最终解析的 json 格式数据:'
        return result;
      }
    },
    uuid(len, radix) {
      var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(
        ""
      );
      var uuid = [],
        i;
      radix = radix || chars.length;

      if (len) {
        // Compact form
        for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
      } else {
        // rfc4122, version 4 form
        var r;

        // rfc4122 requires these characters
        uuid[8] = uuid[13] = uuid[18] = uuid[23] = "-";
        uuid[14] = "4";

        // Fill in random data.  At i==19 set the high bits of clock sequence as
        // per rfc4122, sec. 4.1.5
        for (i = 0; i < 36; i++) {
          if (!uuid[i]) {
            r = 0 | (Math.random() * 16);
            uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
          }
        }
      }
      return uuid.join("");
    },
    beforeClose(done){
      this.reset()
      this.$emit('update:importVisualDialogFlag',false);
      // done()
    }
  },
  watch:{
    importType(val){
      if(val){
        this.getImportParams()
      }
    }
  }
}
</script>

<style scoped>
</style>